/*
 * Copyright 2010-2011 CGT&DC ISA RAS
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package websolve.workflow.wfms.security;

import java.security.Principal;
import java.util.logging.Logger;

import javax.servlet.ServletContext;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import websolve.everest.security.AccessPolicy;
import websolve.workflow.wfms.WorkflowManager;

public class AuthzManager {

    private AccessPolicy accessPolicy;
    private WorkflowManager wfMan;

    public AuthzManager(AccessPolicy accessPolicy, WorkflowManager wfMan) {
        this.accessPolicy = accessPolicy;
        this.wfMan = wfMan;
    }

    public void authorize(AuthzContext ctx) {

        if (ctx.getSecurityContext().isSecure()) {
            boolean auth = false;
            Principal user = ctx.getSecurityContext().getUserPrincipal();
            if (user != null) {
                if (accessPolicy.isAllowed(user.getName()) && !accessPolicy.isDenied(user.getName())) {
                    if (ctx.getResourceType().equals(AuthzContext.WORKFLOW_RESOURCE)
                            && (ctx.getMethod().equals(HttpMethod.PUT) || ctx.getMethod().equals(HttpMethod.DELETE))) {
                        String owner = wfMan.getWorkflow(ctx.getResourceId()).getOwner();
                        if (owner == null) {
                            auth = true;
                        } else {
                            if (user.getName().equals(owner)) {
                                auth = true;
                            }
                        }
                    } else {
                        auth = true;
                    }
                } else {
                    // allow read-only access to workflows for authenticated users
                    if ((ctx.getResourceType().equals(AuthzContext.WORKFLOW_RESOURCE) 
                            || ctx.getResourceType().equals(AuthzContext.WORKFLOWS_RESOURCE)) 
                            && (ctx.getMethod().equals(HttpMethod.GET))) {
                        auth = true;
                    }
                }
            }
            if (auth) {
                log.info("Authorized: " + user.getName() + " "
                        + ctx.getResourceType() + " " + (ctx.getResourceId() != null ? ctx.getResourceId() + " " : "")
                        + ctx.getMethod());
            } else {
                log.info("Unauthorized: "
                        + (user != null ? user.getName() : "ANONYMOUS") + " " + ctx.getResourceType() + " "
                        + (ctx.getResourceId() != null ? ctx.getResourceId() + " " : "") + ctx.getMethod());
                throw new WebApplicationException(Response.status(Status.UNAUTHORIZED).build());
            }
        } else {
            // security is not enabled
        }
    }

    public static AuthzManager getInstance(ServletContext ctx) {
        return (AuthzManager) (ctx.getAttribute("authz-manager"));
    }

    private static final Logger log = Logger.getLogger(AuthzManager.class.getName());
}
